#include <GameEngine/Multimedia/music_observer.h>



#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

#ifndef DOXYGEN_IGNORE
#include "music_observer.moc"
#endif

//! Constructor from a refresh rate and a music
/*!
 @param refresh_rate The frequency at which the state of the music should be checked,
                     specified in milliseconds
 @param music The music to be observed
 @note This constructor is private and should never be accessed by client code. To
       create a music observer, please use the create_observer function
 */
 MusicObserver::MusicObserver(MilliSeconds refresh_rate, const Music& music) : music_(&music), previous_state_(music.state()), QTimer() {
	// Setup connections
	QObject::connect(music_, SIGNAL(destroyed()), this, SLOT(clean()));
	QObject::connect(this, SIGNAL(timeout()), this, SLOT(refresh()));

	// Start the timer
	start(refresh_rate);
}

//! Destructor
MusicObserver::~MusicObserver() {}

//! Create a music observer
/*!
 @param refresh_rate The frequency at which the state of the music should be checked,
                     specified in milliseconds
 @param music The music to be observed
 @return A new music observer. You can delete this observer in your client code, but
         need not to do so since this class handles its own memory management (the
		 observer is then destroyed when the music itself is destroyed)
 @note The music class is handled as a resource, which allows several music instances
       to share the same music player. This observer is attached to one specific music
	   instance, NOT to the music player itself
 */
MusicObserver* MusicObserver::create_observer(MilliSeconds refresh_rate, const Music& music) {
	return new MusicObserver(refresh_rate, music);
}

//! Update the refresh rate
/*!
 @param refresh_rate The new frequency at which the state of the music should be checked,
                     specified in milliseconds
 */
void MusicObserver::set_refresh_rate(MilliSeconds refresh_rate) {
	setInterval(refresh_rate);
}

//! Accessor to the music handled by the observer (read only)
/*!
 @return A constant pointer to the music handled by the observer
 */
const Music* MusicObserver::music() const {
	return music_;
}

//! Refreshes informations about the state of the music if necessary
/*!
 *  If the state of the music has changed, an appropriate signal is emitted
 */
void MusicObserver::refresh() {
	// Check the music pointer
	if ( music_ == nil ) return;

	// Get the current music state
	Music::PlayerState state = music_->state();
	if ( state == previous_state_ ) return;
	previous_state_ = state;

	if ( state == Music::Playing ) {
		emit music_started();
	}
	else if ( state == Music::Paused ) {
		emit music_paused();
	}
	else if ( state == Music::Stopped ) {
		emit music_stopped();
	}
	else if ( state == Music::Invalid ) {
		emit music_invalid();
	}
}

//! Clean memory allocated for the observer
/*!
 *  This function emits the music_destroyed() signal
 *
 @note Clean the memory associated to the observer, calling the deleteLater function
 */
void MusicObserver::clean() {
	emit music_destroyed();
	deleteLater();
}

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif
